<template>
  <!--  储位  -->
  <div class="card-box card-box-top">
    <h2>储位管理</h2>
    <!--  加载动画  -->
    <div v-show="state.showTreeLoading" class="loading-animation">
      <div>
        <Spin style="margin: auto 20px" />加载中...
      </div>
    </div>

    <div v-show="state.treeList.length" class="storage-level">
      <template v-for="(item, index) in state.treeList" :key="index">
        <!--          保藏区-->
        <LevelBox v-if="index === 0" :level-index="index" :current-index="state.indexList[index]" :list="item"
          :level-type="1" title="保藏区" :isTransit="isTransit" @add-btn-click="showSaveModalFn('新增')"
          @box-click="changeTreeListFn">
          <template #modal="saveProps">
            <img class="edit-btn" v-if="!saveProps.data?.usedCount" style="margin-right: 30px"
              src="@/assets/images/del.png" alt="" @click.stop="delSaveFn(saveProps.data)" />
            <img class="edit-btn" src="@/assets/images/edit.png" alt=""
              @click.stop="showSaveModalFn('修改', saveProps.data)" />
          </template>
        </LevelBox>

        <!--          设备-->
        <LevelBox v-else-if="index === 1 && state.treeList[0]?.length - 1 !== state.indexList[0]" :level-index="index"
          :current-index="state.indexList[index]" :list="item" title="设备" :level-type="2" :isTransit="isTransit"
          @add-btn-click="showEquipmentModalFn('新增')" @box-click="changeTreeListFn">
          <template #modal="equipmentProps">
            <img class="edit-btn" v-if="!equipmentProps.data?.usedCount" style="margin-right: 30px"
              src="@/assets/images/del.png" alt="" @click.stop="delEquipmentFn(equipmentProps.data)" />
            <img class="edit-btn" src="@/assets/images/edit.png" alt=""
              @click.stop="showEquipmentModalFn('修改', equipmentProps.data)" />
          </template>
        </LevelBox>

        <!--          盒位-->
        <LevelBox v-else-if="index === state.treeList.length - 1" :level-index="index"
          :current-index="state.indexList[index]" :list="item" :level-type="3" title="盒位" :isTransit="isTransit"
          @add-btn-click="addLevelFn" @box-click="changeTreeListFn">
          <template #modal="boxProps">
            <template v-if="boxProps.data?.boxUsedCount === 0">
              <img class="edit-btn" v-if="item?.length > 1 && boxProps.data?.deviceId === 0" style="margin-right: 30px"
                src="@/assets/images/del.png" alt="" @click.stop="delLevelFn(boxProps)" />
              <img class="edit-btn" src="@/assets/images/lock.png" alt="" @click.stop="lockFn(boxProps.data)" />
            </template>
            <img class="edit-btn" v-else-if="boxProps.data?.usedCount > 0" src="@/assets/images/unlock.png" alt=""
              @click.stop />
            <img class="edit-btn" v-else-if="boxProps.data?.boxEmptyCount === 1" src="@/assets/images/cannotlock.png"
              alt="" @click.stop="unlockFn(boxProps.data)" />
          </template>
        </LevelBox>

        <!--          常规-->
        <LevelBox v-else :level-index="index" :current-index="state.indexList[index]" :title="item[0]?.levelName"
          :list="item" :show-add-btn="true" :isTransit="isTransit" @add-btn-click="addLevelFn"
          @box-click="changeTreeListFn">
          <template #modal="levelProps">
            <img class="edit-btn" src="@/assets/images/del.png" alt="" @click.stop="delLevelFn(levelProps)" />
          </template>
        </LevelBox>
      </template>
    </div>
  </div>

  <!--  盒子  -->
  <div class="card-box card-box-bottom">
    <div v-if="state.showBoxLoading" style="display: flex; align-items: center; justify-content: center; height: 300px">
      <Spin />
    </div>
    <div v-show="!state.showBoxLoading">
      <div class="box-header">
        <span>
          冻存盒编号：
          <Popover>
            <template #content>
              <div>{{ state.boxInfo?.serial }}</div>
            </template>
            {{ handleTitle(state.boxInfo?.serial) }}
          </Popover>
        </span>
        <span>冻存盒类型：
          <Popover>
            <template #content>
              <div>{{ state.boxInfo?.boxSerial }}</div>
            </template>
            {{ handleTitle(state.boxInfo?.boxSerial) }}
          </Popover>
        </span>
        <span>冻存盒状态：{{ getStateFn(state.boxInfo?.status) }}</span>
        <span>冻存盒位置：
          <Popover>
            <template #content>
              <div>{{ state.boxInfo?.storageDesp }}</div>
            </template>
            {{ handleTitle(state.boxInfo?.storageDesp) }}
          </Popover>
        </span>
        <span>已存放支数：{{ state.boxInfo?.existCount ?? '-' }}</span>
        <span>剩余孔位数：{{ state.boxInfo?.availableCount ?? '-' }}</span>
        <span>项目组：
          <Popover>
            <template #content>
              <div>{{ state.boxInfo?.projectNames }}</div>
            </template>
            {{ handleTitle(state.boxInfo?.projectNames) }}
          </Popover>
        </span>
      </div>
      <div class="box-table">
        <StorageBox :cols="state.boxInfo?.cols" :row="state.boxInfo?.rows" :draggable="true" :list="state.boxList"
          :scale="0.7" />
        <vxe-table ref="tableRef" height="auto" round stripe style="flex: 1" :data="state.boxList" size="mini">
          <vxe-column field="strainIndex" title="位置"
            :formatter="({ cellValue }) => subscript(cellValue, state.boxInfo?.rows)" />
          <vxe-column field="specimen" title="样本编号" :formatter="({ cellValue }) => cellValue?.originalSerial" />
          <vxe-column field="specimen" title="样本名称" :formatter="({ cellValue }) => cellValue?.name" />
          <vxe-column field="specimen" title="采样日期" :formatter="({ cellValue }) => cellValue?.sampleTime" />
          <vxe-column field="serial" title="数字编号" />
          <vxe-column field="capacity" title="容量"
            :formatter="({ cellValue, row }) => `${unitCheck(cellValue, row.unit)}`" />
        </vxe-table>
      </div>
    </div>
  </div>

  <!-- 保藏弹窗 -->
  <SaveModal v-model:show-modal="state.showSaveModal" :data="state.currentData" :title="state.modalType"
    @edit-modal-ok="getStorageListFn(0)" />
  <!-- 设备弹窗 -->
  <EquipmentModal v-if="state.treeList[0] && state.treeList[0][state.indexList[0]]?.storageId"
    v-model:show-modal="state.showEquipmentModal" :data="state.currentData" :title="state.modalType"
    :freezer-box-id="state.treeList[0][state.indexList[0]]?.storageId"
    @edit-modal-ok="getStorageListFn(state.treeList[0][state.indexList[0]]?.storageId, 0)" />
  <!-- 冻存盒弹窗 -->
  <FreezerBoxModal v-model:show-modal="state.showBoxModal" :data="state.currentData"
    @edit-modal-ok="getStorageListFn(state.treeList[state.treeList.length - 2][state.indexList[state.treeList.length - 2]].storageId, state.treeList.length - 2)" />
</template>

<script setup lang="ts">
import StorageBox from '@/modules/underlying-data/pages/storage-management/components/storage-box/storage-box.vue';
import LevelBox from '@/modules/underlying-data/pages/storage-management/components/level-box/level-box.vue';
import SaveModal from '@/modules/underlying-data/pages/storage-management/components/save-modal/save-modal.vue';
import EquipmentModal from '@/modules/underlying-data/pages/storage-management/components/equipment-modal/equipment-modal.vue';
import FreezerBoxModal from '@/modules/underlying-data/pages/storage-management/components/freezer-box-modal/freezer-box-modal.vue';
import { computed, provide, reactive, ref } from 'vue';
import { message, Modal, Spin, Popover } from 'ant-design-vue';
import { getTableList, getStorageList, unBindBox, delSaveOrEquipmentById, addLevel } from '@/modules/underlying-data/api/storage-managment';
import { aloneStrictMode } from '@/modules/sample_manage/api/input_manage';
import { subscript, unitCheck } from '@/libs/utils';
import { getImageFn } from '@/libs/utils';
import { boxSearchAll } from '@/api/base/box_data';

const boxTypeList = ref();
(async () => {
  const res = await boxSearchAll();
  boxTypeList.value = res.result.map((item) => ({
    label: item.serial,
    value: item.id,
  }));
})();
provide('boxTypeList', boxTypeList);
/**
 * const
 */
const tableRef = ref();

/**
 * data
 */
const state: {
  currentData: any;
  modalType: '新增' | '修改';
  treeList: any[];
  indexList: number[];
  boxInfo: any;
  boxList: any[];

  showTreeLoading: boolean;
  showBoxLoading: boolean;
  showSaveModal: boolean;
  showEquipmentModal: boolean;
  showBoxModal: boolean;
} = reactive({
  currentData: {},
  modalType: '新增',
  treeList: [],
  indexList: [],
  boxInfo: {},
  boxList: [],

  showTreeLoading: false,
  showBoxLoading: false,
  showSaveModal: false,
  showEquipmentModal: false,
  showBoxModal: false,
});

const isTransit = computed(() => {
  return state.indexList[0] === state.treeList[0].length - 1;
});

/**
 * fn
 */
// 获取当前索引对应的item
const getBoxItem = (levelIndex) => {
  if (!levelIndex || levelIndex > state.treeList?.length) return false;
  let list = state.treeList[levelIndex];
  let index = state.indexList[levelIndex];
  return list[index];
};
// 数据处理
const getTreeList = (tree: any[]) => {
  let arr: any[] = [];
  const treeToObj = (sub: any[]) => {
    if (!sub || (sub && !sub.length)) return;
    arr.push(sub);
    if (sub[0]?.children) {
      treeToObj(sub[0]?.children);
    }
  };
  treeToObj(tree);
  return arr;
};
const handleTitle = (string: string) => {
  if (!string) return '-';
  return string.length > 6 ? string.slice(0, 6) + '...' : string;
};

/**
 * tree
 */
/**
 * @description 将根据id请求处理后的数组拼接至levelIndex后;
 */
const getStorageListFn = async (id = 0, levelIndex?: number) => {
  state.showTreeLoading = true;
  const res = await getStorageList(id);
  let arr = getTreeList(res?.result);
  if (levelIndex || levelIndex === 0) {
    // 适配新建保藏区
    if (levelIndex === 0 && !arr.length) {
      arr = [[]];
    }
    state.treeList.splice(levelIndex + 1, state.treeList.length, ...arr);
    state.indexList.splice(levelIndex + 1, state.treeList.length, ...new Array(arr.length)?.fill(0));
  } else {
    state.treeList = arr;
    state.indexList = new Array(arr.length).fill(0);
  }
  if (id === 0) {
    state.treeList[0].map(async (item) => {
      if (item.image) {
        item.url = await getImageFn(item.image);
      }
      return item;
    });
  } else if (!levelIndex) {
    state.treeList[1].map(async (item) => {
      if (item.image) {
        item.url = await getImageFn(item.image);
      }
      return item;
    });
  }
  console.log('treeList', state.treeList);
  // 状态
  state.showTreeLoading = false;
  // 盒数据生成
  await getBoxInfoFn(state.treeList[state.treeList?.length - 1][0]);
};
getStorageListFn();
// 切换子tree
const changeTreeListFn = async (info: any) => {
  state.currentData = info.data;
  state.indexList[info.levelIndex] = info.currentIndex;
  if (info.levelIndex === state.treeList.length - 1 && state.treeList.length > 1) {
    await getBoxInfoFn(info.data);
  } else {
    await getStorageListFn(info.data?.storageId, info.levelIndex);
  }
};

/**
 * box
 */
const getStateFn = (value) => {
  switch (value) {
    case 1:
      return '已入库';
    case 2:
      return '待入库';
    case 3:
      return '空盒';
    default:
      return '-';
  }
};
const getBoxInfoFn = async (boxInfo) => {
  state.showBoxLoading = true;
  // 空盒
  if (!boxInfo?.boxId) {
    state.boxInfo = {};
    state.boxList = [];
    state.showBoxLoading = false;
    return;
  }
  // 盒子尺寸，标题信息
  let params = {
    id: boxInfo.boxId,
    // id: 107,
  };
  let res = await getTableList(params);
  state.boxInfo = res.result;
  // 表格及盒子信息
  let sub = await aloneStrictMode(boxInfo.stockId);
  state.boxList = sub.result;
  state.showBoxLoading = false;
};

/**
 * 添加
 */
// 层级-添加
const addLevelFn = async (levelType, levelIndex) => {
  let parentData = getBoxItem(levelIndex - 1);
  const modal = Modal.confirm({
    title: '确认添加？',
    onOk: async () => {
      await addLevel(parentData?.storageId);
      await getStorageListFn(parentData?.storageId, levelIndex - 1);
      modal.destroy();
    },
  });
};
//保藏-添加
const showSaveModalFn = async (params: '新增' | '修改', data?) => {
  state.modalType = params;
  if (params === '新增') {
    state.currentData = {};
  } else {
    state.currentData = data;
  }
  state.showSaveModal = true;
};
//设备-添加
const showEquipmentModalFn = async (params: '新增' | '修改', data?) => {
  state.modalType = params;
  if (params === '新增') {
    state.currentData = {};
  } else {
    state.currentData = data;
  }
  state.showEquipmentModal = true;
};

/**
 * 模态框
 */
// 保藏-删除
const delSaveFn = async (data) => {
  const modal = Modal.confirm({
    title: '确认删除？',
    content: `删除保藏区后，该保藏区下所有设备信息将全部重置且不可恢复！确认删除“保藏区”及关联所有信息？`,
    onOk: async () => {
      await delSaveOrEquipmentById(data.storageId);
      await getStorageListFn();
      message.success('操作成功！');
      modal.destroy();
    },
  });
};
// 设备-删除
const delEquipmentFn = async (data) => {
  const modal = Modal.confirm({
    title: '确认删除？',
    content: `删除设备后，该设备下所有冻存盒位置信息将全部重置且不可恢复！
    确认删除“液氮罐”及关联所有信息？`,
    onOk: async () => {
      await delSaveOrEquipmentById(data.storageId);
      await getStorageListFn(state.treeList[0][state.indexList[0]].storageId, 0);
      message.success('操作成功！');
      modal.destroy();
    },
  });
};
// 层级-删除
const delLevelFn = async (params) => {
  const { data, levelIndex } = params;
  if (state.treeList[levelIndex].length === 1) return;
  if (data?.usedCount > 0) return;
  const modal = Modal.confirm({
    title: '确认删除？',
    content: `删除后，信息将全部重置且不可恢复！`,
    onOk: async () => {
      await delSaveOrEquipmentById(data?.storageId);
      await getStorageListFn(getBoxItem(levelIndex - 1)?.storageId, levelIndex - 1);
      message.success('操作成功！');
      modal.destroy();
    },
  });
};
// 盒-绑定
const lockFn = (data) => {
  state.currentData = data;
  state.showBoxModal = true;
};
// 盒-解绑
const unlockFn = async (data) => {
  const modal = Modal.confirm({
    title: '确认解绑？',
    content: `解绑后，该冻存盒将转移至中转区。确认解绑“${data?.boxSerial}冻存盒”？`,
    onOk: async () => {
      const params = {
        epcId: data?.boxId, //盒id
        storageId: state.treeList[0][state.treeList[0].length - 1]?.storageId, //中转id
      };
      await unBindBox(params);
      await getStorageListFn();
      message.success('操作成功！');
      modal.destroy();
    },
  });
};
</script>

<style scoped lang="less">
.card-box {
  background-color: #fff;
  border-radius: 8px;

  &-top {
    height: 566px;
    padding: 12px 20px 40px;
    overflow: hidden;

    .storage-level {
      display: flex;
      flex-wrap: nowrap;
      padding-bottom: 15px;
      overflow-x: auto;
      overflow-y: hidden;
    }
  }

  &-bottom {
    height: 364px;
    padding: 26px 20px 6px;
    margin-top: 20px;

    .box-header {
      display: flex;
      margin-bottom: 8px;
      font-size: 16px;
      line-height: 24px;

      >span {
        flex: 1;
      }
    }

    .box-table {
      display: flex;
      height: 288px;
    }
  }

  >h2 {
    line-height: 29px;
    font-size: 20px;
    font-weight: 500;
  }
}

.loading-animation {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.edit-btn {
  width: 18px;
  object-fit: contain;
}
</style>
